package org.platform.processor.diagnose.job;

import lombok.extern.slf4j.Slf4j;
import org.platform.core.JobManager;
import org.platform.mo.bussmo.task.TaskExecutorStep;
import org.platform.tool.util.ComUtils;
import org.platform.tool.util.DataFrameUtil;
import org.quartz.JobKey;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.JobDetailImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zeromq.ZMQ;

import javax.annotation.PostConstruct;

/**
 * 对应<站解控管理子系统>文档中 3.5.8 任务执行步骤N.P 章节
 * 用于接收任务执行进度
 *
 * @author FengJie
 * @date 2018/7/11
 */

@Component
@Slf4j
public class ReceiveTaskExecutorStepJob {
    private static final String TOPIC = "TaskSteps_TASK";
    private static final String ADDR = "tcp://127.0.0.1:28881";
    private static final String DATA_KEY = "TaskProcessData";
    private static final String JOB_KEY = "PromoteTaskExecutorStepJob";


    @Autowired
    private JobManager job;

    //TODO 1.当前使用的主题 端口 最终需要和廖必金确认,最终以 [配置文件]的方式使用  2.统一使用线程池的方式管理线程

    @PostConstruct
    public void init() {
        ZMQ.Context context = ZMQ.context(1);
        ZMQ.Socket socket = context.socket(ZMQ.SUB);
        socket.connect(ADDR);
        socket.subscribe(TOPIC);
        new ReceiveThread(socket).start();
    }

    /**
     * 初始化zeroMQ,用于接收数据
     */
    private class ReceiveThread extends Thread {
        private ZMQ.Socket socket;

        ReceiveThread(ZMQ.Socket socket) {
            this.socket = socket;
        }

        @Override
        @SuppressWarnings("InfiniteLoopStatement")
        public void run() {
            while (true) {
                try {
                    //第一次接收到的是主题  第二次接收到的是内容
                    String topic = socket.recvStr(0);
                    if (TOPIC.equals(topic)) {
                        byte[] recv = socket.recv();
                        //截取固定位数据
                        String device = DataFrameUtil.analysis(recv);
                        TaskExecutorStep.TaskProcessData taskProcessData = TaskExecutorStep.TaskProcessData.parseFrom(device.getBytes());
                        addJob(taskProcessData);
                    }
                } catch (Exception e) {
                    log.error("解析【任务执行步骤】参数异常:", e);
                }
            }
        }

        private void addJob(TaskExecutorStep.TaskProcessData taskProcessData) {
            JobDetailImpl jd = new JobDetailImpl();
            jd.setJobClass(PromoteTaskExecutorStepJob.class);
            jd.setKey(JobKey.jobKey(ComUtils.getUUID()));
            jd.getJobDataMap().put(DATA_KEY, taskProcessData);

            SimpleTrigger trigger = TriggerBuilder.newTrigger()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                    .startNow()
                    .build();

            job.register(jd, trigger);
        }
    }

}
